'use strict'

const {parse} = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const t = require('@babel/traverse');
const generator = require('@babel/generator').default;

let code = `function a(){
    var a = 1;
    a = a + 1;
    return a;
}
function b(){
    var b = 1;
    var c = 2;
    b = b - c;
    return b;
}`;

let ast = parse(code);
const visitor = {
    BlockStatement:{
        enter: function(path){
            path.scope.dump();
            console.log('此块节点源码：'+path.toString());
            console.log('--------------------------------------------');
            let bindings = path.scope.bindings;
            console.log('此作用域内的绑定数：'+Object.keys(bindings).length);

            for(const bindingk in bindings){
                const binding = bindings[bindingk];
                // console.log(Object.keys(binding));
                console.log('名字：', bindingk);
                console.log('类型：', binding.kind);
                console.log('定义：', binding.identifier.name, binding.identifier.type);
                console.log('是否会保持不变：', binding.constant);
                console.log('被修改信息NodePath记录');
                for(let violation in binding.constantViolations){
                    console.log(binding.constantViolations[violation].toString(), binding.constantViolations[violation].type);
                }
                console.log('是否会被引用：', binding.referenced);
                console.log('被引用次数', binding.references);
                console.log('被引用信息NodePath记录');
                for(let rp in binding.referencePaths){
                    console.log(binding.referencePaths[rp].toString(), binding.referencePaths[rp].type, binding.referencePaths[rp].parentPath.toString());
                }
            }
        },
    },
}

// traverse(ast, visitor);

/*  另外一个测试
*/

code = `function scopeOnce() {
    var ref = "This is a binding";

    ref; // This is a reference to a binding

    function scopeTwo() {
        ref; // This is a reference to a binding from a lower scope
    }
}`

ast = parse(code);

const visitorx = {
    FunctionDeclaration:{
        enter: function(path){
            path.scope.dump();
        },
    },
}

traverse(ast, visitorx);
